home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16.lha / Python-1.6 / Lib / Python1.6 / test / regrtest.py < prev    next >
Encoding:
Python Source  |  2000-05-05  |  7.7 KB  |  270 lines

  1. #! /usr/bin/env python
  2.  
  3. """Regression test.
  4.  
  5. This will find all modules whose name is "test_*" in the test
  6. directory, and run them.  Various command line options provide
  7. additional facilities.
  8.  
  9. Command line options:
  10.  
  11. -v: verbose  -- run tests in verbose mode with output to stdout
  12. -q: quiet    -- don't print anything except if a test fails
  13. -g: generate -- write the output file for a test instead of comparing it
  14. -x: exclude  -- arguments are tests to *exclude*
  15. -s: single   -- run only a single test (see below)
  16.  
  17. If non-option arguments are present, they are names for tests to run,
  18. unless -x is given, in which case they are names for tests not to run.
  19. If no test names are given, all tests are run.
  20.  
  21. -v is incompatible with -g and does not compare test output files.
  22.  
  23. -s means to run only a single test and exit.  This is useful when Purifying
  24. the Python interpreter.  The file /tmp/pynexttest is read to find the next
  25. test to run.  If this file is missing, the first test_*.py file in testdir or
  26. on the command line is used.  (actually tempfile.gettempdir() is used instead
  27. of /tmp).
  28.  
  29. """
  30.  
  31. import sys
  32. import string
  33. import os
  34. import getopt
  35. import traceback
  36.  
  37. import test_support
  38.  
  39. def main(tests=None, testdir=None):
  40.     """Execute a test suite.
  41.  
  42.     This also parses command-line options and modifies its behaviour
  43.     accordingly. 
  44.  
  45.     tests -- a list of strings containing test names (optional)
  46.     testdir -- the directory in which to look for tests (optional)
  47.  
  48.     Users other than the Python test suite will certainly want to
  49.     specify testdir; if it's omitted, the directory containing the
  50.     Python test suite is searched for.  
  51.  
  52.     If the tests argument is omitted, the tests listed on the
  53.     command-line will be used.  If that's empty, too, then all *.py
  54.     files beginning with test_ will be used.
  55.     
  56.     """
  57.     
  58.     try:
  59.         opts, args = getopt.getopt(sys.argv[1:], 'vgqxs')
  60.     except getopt.error, msg:
  61.         print msg
  62.         print __doc__
  63.         return 2
  64.     verbose = 0
  65.     quiet = 0
  66.     generate = 0
  67.     exclude = 0
  68.     single = 0
  69.     for o, a in opts:
  70.         if o == '-v': verbose = verbose+1
  71.         if o == '-q': quiet = 1; verbose = 0
  72.         if o == '-g': generate = 1
  73.         if o == '-x': exclude = 1
  74.         if o == '-s': single = 1
  75.     if generate and verbose:
  76.         print "-g and -v don't go together!"
  77.         return 2
  78.     good = []
  79.     bad = []
  80.     skipped = []
  81.  
  82.     if single:
  83.         from tempfile import gettempdir
  84.         filename = os.path.join(gettempdir(), 'pynexttest')
  85.         try:
  86.             fp = open(filename, 'r')
  87.             next = string.strip(fp.read())
  88.             tests = [next]
  89.             fp.close()
  90.         except IOError:
  91.             pass
  92.     for i in range(len(args)):
  93.         # Strip trailing ".py" from arguments
  94.         if args[i][-3:] == '.py':
  95.             args[i] = args[i][:-3]
  96.     stdtests = STDTESTS[:]
  97.     nottests = NOTTESTS[:]
  98.     if exclude:
  99.         for arg in args:
  100.             if arg in stdtests:
  101.                 stdtests.remove(arg)
  102.         nottests[:0] = args
  103.         args = []
  104.     tests = tests or args or findtests(testdir, stdtests, nottests)
  105.     if single:
  106.         tests = tests[:1]
  107.     test_support.verbose = verbose      # Tell tests to be moderately quiet
  108.     save_modules = sys.modules.keys()
  109.     for test in tests:
  110.         if not quiet:
  111.             print test
  112.         ok = runtest(test, generate, verbose, testdir)
  113.         if ok > 0:
  114.             good.append(test)
  115.         elif ok == 0:
  116.             bad.append(test)
  117.         else:
  118.             if not quiet:
  119.                 print "test", test,
  120.                 print "skipped -- an optional feature could not be imported"
  121.             skipped.append(test)
  122.         # Unload the newly imported modules (best effort finalization)
  123.         for module in sys.modules.keys():
  124.             if module not in save_modules and module.startswith("test."):
  125.                 test_support.unload(module)
  126.     if good and not quiet:
  127.         if not bad and not skipped and len(good) > 1:
  128.             print "All",
  129.         print count(len(good), "test"), "OK."
  130.     if bad:
  131.         print count(len(bad), "test"), "failed:",
  132.         print string.join(bad)
  133.     if skipped and not quiet:
  134.         print count(len(skipped), "test"), "skipped:",
  135.         print string.join(skipped)
  136.  
  137.     if single:
  138.         alltests = findtests(testdir, stdtests, nottests)
  139.         for i in range(len(alltests)):
  140.             if tests[0] == alltests[i]:
  141.                 if i == len(alltests) - 1:
  142.                     os.unlink(filename)
  143.                 else:
  144.                     fp = open(filename, 'w')
  145.                     fp.write(alltests[i+1] + '\n')
  146.                     fp.close()
  147.                 break
  148.         else:
  149.             os.unlink(filename)
  150.  
  151.     return len(bad) > 0
  152.  
  153. STDTESTS = [
  154.     'test_grammar',
  155.     'test_opcodes',
  156.     'test_operations',
  157.     'test_builtin',
  158.     'test_exceptions',
  159.     'test_types',
  160.    ]
  161.  
  162. NOTTESTS = [
  163.     'test_support',
  164.     'test_b1',
  165.     'test_b2',
  166.     ]
  167.  
  168. def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
  169.     """Return a list of all applicable test modules."""
  170.     if not testdir: testdir = findtestdir()
  171.     names = os.listdir(testdir)
  172.     tests = []
  173.     for name in names:
  174.         if name[:5] == "test_" and name[-3:] == ".py":
  175.             modname = name[:-3]
  176.             if modname not in stdtests and modname not in nottests:
  177.                 tests.append(modname)
  178.     tests.sort()
  179.     return stdtests + tests
  180.  
  181. def runtest(test, generate, verbose, testdir = None):
  182.     """Run a single test.
  183.     test -- the name of the test
  184.     generate -- if true, generate output, instead of running the test
  185.     and comparing it to a previously created output file
  186.     verbose -- if true, print more messages
  187.     testdir -- test directory
  188.     """
  189.     test_support.unload(test)
  190.     if not testdir: testdir = findtestdir()
  191.     outputdir = os.path.join(testdir, "output")
  192.     outputfile = os.path.join(outputdir, test)
  193.     try:
  194.         if generate:
  195.             cfp = open(outputfile, "w")
  196.         elif verbose:
  197.             cfp = sys.stdout
  198.         else:
  199.             cfp = Compare(outputfile)
  200.     except IOError:
  201.         cfp = None
  202.         print "Warning: can't open", outputfile
  203.     try:
  204.         save_stdout = sys.stdout
  205.         try:
  206.             if cfp:
  207.                 sys.stdout = cfp
  208.                 print test              # Output file starts with test name
  209.             __import__(test, globals(), locals(), [])
  210.         finally:
  211.             sys.stdout = save_stdout
  212.     except ImportError, msg:
  213.         return -1
  214.     except KeyboardInterrupt, v:
  215.         raise KeyboardInterrupt, v, sys.exc_info()[2]
  216.     except test_support.TestFailed, msg:
  217.         print "test", test, "failed --", msg
  218.         return 0
  219.     except:
  220.         type, value = sys.exc_info()[:2]
  221.         print "test", test, "crashed --", type, ":", value
  222.         if verbose:
  223.             traceback.print_exc(file=sys.stdout)
  224.         return 0
  225.     else:
  226.         return 1
  227.  
  228. def findtestdir():
  229.     if __name__ == '__main__':
  230.         file = sys.argv[0]
  231.     else:
  232.         file = __file__
  233.     testdir = os.path.dirname(file) or os.curdir
  234.     return testdir
  235.  
  236. def count(n, word):
  237.     if n == 1:
  238.         return "%d %s" % (n, word)
  239.     else:
  240.         return "%d %ss" % (n, word)
  241.  
  242. class Compare:
  243.  
  244.     def __init__(self, filename):
  245.         self.fp = open(filename, 'r')
  246.  
  247.     def write(self, data):
  248.         expected = self.fp.read(len(data))
  249.         if data <> expected:
  250.             raise test_support.TestFailed, \
  251.                     'Writing: '+`data`+', expected: '+`expected`
  252.  
  253.     def writelines(self, listoflines):
  254.         map(self.write, listoflines)
  255.  
  256.     def flush(self):
  257.         pass
  258.  
  259.     def close(self):
  260.         leftover = self.fp.read()
  261.         if leftover:
  262.             raise test_support.TestFailed, 'Unread: '+`leftover`
  263.         self.fp.close()
  264.  
  265.     def isatty(self):
  266.         return 0
  267.  
  268. if __name__ == '__main__':
  269.     sys.exit(main())
  270.